<?php
/**
 * Created by PhpStorm.
 * Script Name: OpenPlatform.php
 * Create: 2022/12/22 18:05
 * Description:
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace plugin\wechat\app\service;

use EasyOpen\Tencent\Request\Mp\ComponentFastregisterweapp;
use EasyOpen\Tencent\Request\Mp\ComponentModifyWxaJumpDomain;
use EasyOpen\Tencent\Request\Mp\ComponentModifyWxaServerDomain;
use EasyOpen\Tencent\Request\Mp\WxaComponentFastregisterbetaweapp;
use EasyWeChat\Factory;
use plugin\wechat\app\service\Setting as SettingService;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;

class OpenPlatform extends Common
{
    private static $openPlatform = null;

    /**
     * 设置开放平台业务域名
     * @param array $params
     * @return bool|mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function jumpDomainModify($params = []){
        $request = new ComponentModifyWxaJumpDomain();
        $request->setAction('set');
        $request->setIsModifyPublishedTogether(true);
        $request->setWxaJumpH5Domain($params['wxa_jump_h5_domain']);
        $response = self::tencentOpenCli()->execute($request, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return true;
    }

    /**
     * 获取开放平台正式版业务域名
     * @return mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function jumpDomainGet(){
        $request = new ComponentModifyWxaJumpDomain();
        $request->setAction('get');
        $response = self::tencentOpenCli()->execute($request, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return $response['data'];
    }

    /**
     * 设置开放平台正式版服务器域名
     * @param array $params
     * @return bool|mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function serverDomainModify($params = []){
        $request = new ComponentModifyWxaServerDomain();
        $request->setAction('set');
        $request->setIsModifyPublishedTogether(true);
        $request->setWxaServerDomain($params['wxa_server_domain']);
        $response = self::tencentOpenCli()->execute($request, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return true;
    }

    /**
     * 获取开放平台正式版服务器域名
     * @return mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function serverDomainGet(){
        $request = new ComponentModifyWxaServerDomain();
        $request->setAction('get');
        $response = self::tencentOpenCli()->execute($request, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return $response['data'];
    }

    static function getComponentAccessToken(){
        try {
            $token = self::getOpenPlatform()->access_token->getToken();
            if(!empty($token['component_access_token'])){
                $token = self::getOpenPlatform()->access_token->getToken(true);
            }
            return $token['component_access_token'];
        }catch (\Exception $e){
            return '';
        }
    }

    /**
     * 微信平台错误
     * @param null $id
     * @param string $default
     * @return array|mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function errors($id = null, $default = ''){
        $list = [
            40013 => 'appid错误',
            48006 => '一个月10次的机会用完了',
            76021 => '接口地址填错了',
            76022 => '当前调用接口使用的 token 与api所属账号不符'
        ];
        return isset($list[$id]) ? $list[$id] : ($default ?: $list);
    }

    /**
     * 获取开放平台app
     * @return \EasyWeChat\OpenPlatform\Application|null
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function getOpenPlatform(){
        $request = request();
        $platform = SettingService::getSettings('platform');
        if(empty($platform)){
            halt("开放平台参数未配置");
        }
        $config = [
            'app_id' => $platform['appid'],
            'secret'   => $platform['appsecret'],
            'token'    => $platform['token'],
            'aes_key'  => $platform['aes_key'],
            'response_type' => 'array',
            'log' => [
                'default' => getenv('APP_DEBUG') ? 'dev' : 'prod' , // 默认使用的 channel，生产环境可以改为下面的 prod
                'channels' => [
                    // 测试环境
                    'dev' => [
                        'driver' => 'single',
                        'path' => runtime_path() . '/logs/wechat/openplatform.log',
                        'level' => 'debug',
                    ],
                    // 生产环境
                    'prod' => [
                        'driver' => 'daily',
                        'path' => runtime_path() . '/logs/wechat/openplatform.log',
                        'level' => 'error',
                        'days' => 3
                    ],
                ],
            ],
            'http' => [
                'timeout' => 0,
                'connect_timeout' => 0
            ]
        ];
        $app = Factory::openPlatform($config);
        if($request) {
            $symfony_request = new SymfonyRequest($request->get(), $request->post(), [], $request->cookie(), [], [], $request->rawBody());
            $symfony_request->headers = new HeaderBag($request->header());
            $app->rebind('request', $symfony_request);
        }

        $app->rebind('cache', new RedisAdapter(self::deserveRedis()));
        return $app;
    }

    /**
     * 官方测试号
     * @return array
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function testApps(){
        return [
            'wx570bc396a51b8ff8','wx9252c5e0bb1836fc','wx8e1097c5bc82cde9','wx14550af28c71a144','wxa35b9c23cfe664eb', //mp
            'wxd101a85aa106f53e','wxc39235c15087f6f3','wx7720d01d4b2a4500','wx05d483572dcd5d8b','wx5910277cae6fd970'  //mini
        ];
    }

    /**
     * 注册小程序:新增|查询
     * @param $params
     * @return bool|mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function registerMiniprogram($params, $action='create'){
        $req = new ComponentFastregisterweapp();
        $req->setAction($action);
        $req->setName($params['name']);
        $req->setLegalPersonaWechat($params['legal_persona_wechat']);
        $req->setLegalPersonaName($params['legal_persona_name']);
        switch ($action) {
            case 'search':
                // code...
                break;
            
            default:
                $req->setCode($params['code']);
                $req->setCodeType($params['code_type']);
                !empty($params['component_phone']) && $req->setComponentPhone($params['component_phone']);
                break;
        }
        
        $response = self::tencentOpenCli()->execute($req, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return true;
    }

    /**
     * 注册试用小程序
     * @param $params
     * @return bool|mixed
     * @throws \Exception
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function registerBetaMiniprogram($params){
        $req = new WxaComponentFastregisterbetaweapp();
        $req->setName($params['name']);
        $req->setOpenid($params['openid']);

        $response = self::tencentOpenCli()->execute($req, self::getComponentAccessToken());
        if(empty($response['code'])){
            return $response['errmsg'];
        }
        return $response;
    }
}